<template>
    <el-main>
        <!-- 搜索栏 -->
        <el-form :model="pageSearchForm" :inline="true" size="default">
            <el-form-item>
                <el-input placeholder="角色名称" v-model="pageSearchForm.roleName"></el-input>
            </el-form-item>
            <el-form-item>
                <el-button icon="Search" @click="onSearch">搜索</el-button>
                <el-button icon="Close" type="danger" plain @click="onReset">重置</el-button>
                <el-button v-permission="['sys:role:add']" icon="Plus" type="primary" size="small"
                    @click="onNewAdd">新增</el-button>
            </el-form-item>
        </el-form>

        <!-- 表格数据 -->
        <el-table :height="tableHeight" :data="tableData" border stripe>
            <el-table-column prop="roleName" label="角色名"></el-table-column>
            <el-table-column prop="remark" label="备注"></el-table-column>
            <el-table-column v-if="global.$hasPerm(['sys:role:assign', 'sys:role:edit', 'sys:role:delete'])" label="操作"
                align="center">
                <template #default="scope">
                    <el-button v-permission="['sys:role:assign']" type="primary" plain icon="Setting" size="small"
                        @click="onAssignMenu(scope.row)">分配菜单</el-button>
                    <el-button v-permission="['sys:role:edit']" type="primary" icon="Edit" size="small"
                        @click="onEdit(scope.row)">编辑</el-button>
                    <el-button v-permission="['sys:role:delete']" type="danger" icon="Delete" size="small"
                        @click="onDelete(scope.row)">删除</el-button>
                </template>
            </el-table-column>
        </el-table>

        <!-- 分页 -->
        <el-pagination @size-change="sizeChange" @current-change="currentChange"
            :current-page.sync="pageSearchForm.currentPage" :page-sizes="[10, 20, 30, 50, 60, 80, 100]"
            :page-size="pageSearchForm.pageSize" layout="total, sizes, prev, pager, next, jumper"
            :total="pageSearchForm.total" background>
        </el-pagination>

        <!-- 新增、编辑弹框 -->
        <SysDialog :title="dialog.title" :width="dialog.width" :visible="dialog.visible" @on-close="onDialogClose"
            @on-confirm="onSubmit">
            <template #content>
                <el-form :model="roleForm" ref="roleFormRef" :rules="rules" label-width="80px" :inline="false"
                    size="default">
                    <el-form-item prop="roleName" label="角色名称">
                        <el-input v-model="roleForm.roleName"></el-input>
                    </el-form-item>
                    <el-form-item prop="remark" label="备注">
                        <el-input v-model="roleForm.remark"></el-input>
                    </el-form-item>
                </el-form>
            </template>
        </SysDialog>
    </el-main>

    <MenuTreeDialog ref="menuTreeDialogRef"></MenuTreeDialog>
</template>

<script setup lang="ts">
import { nextTick, onMounted, reactive, ref } from "vue"
import SysDialog from "@/components/SysDialog.vue"
import useDialog from '../../../hooks/useDialog'
import useInstance from '../../../hooks/useInstance'
import { ElMessage, type FormInstance } from "element-plus"
import { RoleApi } from "../../../api/role"
import { type RoleVO, type RolePageQuery } from "../../../api/role/RoleModel"
import MenuTreeDialog from "./MenuTreeDialog.vue"

// 表单ref属性
const roleFormRef = ref<FormInstance>()
// 弹框属性
const { dialog, onDialogShow, onDialogClose } = useDialog()
// 表单绑定的对象
const pageSearchForm: RolePageQuery = reactive({
    currentPage: 1,
    pageSize: 10,
    roleName: "",
    total: 0
});
// 新增按钮
const onNewAdd = () => {
    dialog.title = "新增角色"
    // 显示弹框
    onDialogShow()
    roleFormRef.value?.resetFields()
}
// 新增表单对象
const roleForm = reactive({
    roleId: "",
    roleName: "",
    remark: ""
})
// 表单验证规则
const rules = reactive({
    roleName: [
        {
            required: true,
            message: "请输入角色名称",
            trigger: "change"
        }
    ]
});

// 搜索
const onSearch = () => {
    queryTableData()
}
// 重置
const onReset = () => {
    pageSearchForm.currentPage = 1
    pageSearchForm.pageSize = 10
    pageSearchForm.roleName = ''
    queryTableData()
}

const tableData = ref<RoleVO[]>([])
const queryTableData = async () => {
    const res = await RoleApi.page(pageSearchForm)
    tableData.value = res.data.records
    pageSearchForm.total = res.data.total
}

let dialogType: 'newAdd' | 'edit' = 'newAdd'
// 表单提交
const onSubmit = () => {
    roleFormRef.value?.validate(async (valid) => {
        if (valid) {
            let res
            if (dialogType === 'newAdd') {
                res = await RoleApi.newAdd(roleForm)
            } else if (dialogType === 'edit') {
                res = await RoleApi.edit(roleForm)
            }
            if (res && res.code === 200) {
                ElMessage.success(res.msg)
                onDialogClose()
                queryTableData()
            }
        }
    })
}

const { global } = useInstance()
const onDelete = async (row: RoleVO) => {
    const confirm = await global.$jagochanConfirm(`确定删除【${row.roleName}】角色吗？`)
    if (confirm) {
        let res = await RoleApi.delete(row.roleId)
        if (res && res.code == 200) {
            ElMessage.success(res.msg)
            queryTableData()
        }
    }
}
const onEdit = (row: RoleVO) => {
    dialogType = 'edit'
    // 显示弹框
    onDialogShow()
    dialog.title = "编辑角色"
    nextTick(() => {
        // 回显数据
        Object.assign(roleForm, row);
    })
    // 清空表单
    roleFormRef.value?.resetFields()
}
// 页容量改变时触发
const sizeChange = (size: number) => {
    pageSearchForm.pageSize = size
    queryTableData()
}
// 页数改变时触发
const currentChange = (page: number) => {
    pageSearchForm.currentPage = page
    queryTableData()
}

const menuTreeDialogRef = ref()
/**
 * 给角色分配菜单 <br/>
 * 显示菜单树。如果是超级管理员👉显示全部的菜单；如果是普通用户👉仅显示该用户拥有的菜单
 */
const onAssignMenu = (row: RoleVO) => {
    menuTreeDialogRef.value.showMenuTreeDialog(row.roleName, row.roleId)
}

const tableHeight = ref(0)
onMounted(() => {
    nextTick(() => {
        tableHeight.value = window.innerHeight - 230
    })

    queryTableData()
})
</script>

<style scoped></style>
